package com.xiangxiangjd.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xiangxiangjd.bean.*;
import com.xiangxiangjd.bean.vo.ClaimDateNoDocx;
import com.xiangxiangjd.controller.helper.$;
import com.xiangxiangjd.mapper.ClaimDateNoMapper;
import com.xiangxiangjd.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiangxiangjd.bean.result.ResultPage;
import com.xiangxiangjd.controller.model.ApiResultModel;

import com.xiangxiangjd.utils.OddNumber;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 申领航材批次号 服务实现类
 *
 * @author 肖守凯
 * @since 2021-11-08
 */
@Service
public class ClaimDateNoServiceImpl extends ServiceImpl<ClaimDateNoMapper, ClaimDateNo>
    implements ClaimDateNoService {

  // 物品和申领单号
  @Autowired ClaimGoodsService claimGoodsService;

  // 物品
  @Autowired GoodsService goodsService;

  // 申领耗材添加
  @Autowired ClaimConsumablesService claimConsumablesService;


  @Autowired UnitService unitService;

  /**
   * 添加ClaimDateNo
   *
   * @param claimDateNo 前端传进的参数
   * @return 返回统一信息
   */
  @Transactional(isolation = Isolation.READ_COMMITTED)
  @Override
  public ApiResultModel addClaimDateNo(ClaimDateNo claimDateNo) {

    // 查询最后一次生成的单号
    String claimOddNumber = baseMapper.getLastClaimOddNumber();

    // 给单号 赋值
    claimDateNo.setClaimOddNumber(OddNumber.getOddNumber("SL", claimOddNumber));

    // 添加单号 获取id
    if (!this.save(claimDateNo)) {
      throw new RuntimeException("添加失败");
    }

    // 申领航材和耗材 赋值单号的id
    List<ClaimGoods> claimGoodsList =
        claimDateNo.getClaimGoodsList().stream()
            .map(
                o -> {
                  o.setClaimId(claimDateNo.getId());
                  return o;
                })
            .collect(Collectors.toList());

    boolean b = claimGoodsService.saveBatch(claimGoodsList);
    if (!b) {
      throw new RuntimeException("添加物品失败");
    }

    return $.success("申领成功，请等待管理员审批");
  }
  /**
   * 编辑跳转页面的回显数据ClaimDateNo
   *
   * @param id 前端传进的参数
   * @return 返回实体类
   */
  @Override
  public ClaimDateNo selectClaimDateNoByIdClaimDateNo(String id) {
    return this.getById(id);
  }

  /**
   * 编辑ClaimDateNo
   *
   * @param claimDateNo 前端传进的参数
   * @return 返回统一信息
   */
  @Override
  public ApiResultModel editClaimDateNo(ClaimDateNo claimDateNo) {
    if (this.updateById(claimDateNo)) {
      return $.success();
    } else {
      return $.error("编辑失败");
    }
  }
  /**
   * 删除一条ClaimDateNo
   *
   * @param ids 前端传进的ID
   * @return 返回统一信息
   */
  @Override
  public ApiResultModel delClaimDateNos(List ids) {

    int i = baseMapper.deleteBatchIds(ids);

    return $.success(i);
  }

  /**
   * 分页查询ClaimDateNo
   *
   * @param page 页码
   * @param limit 查几条
   * @param claimDateNo 前端传进的参数
   * @return 返回统一分页信息
   */
  @Override
  public ResultPage findClaimDateNoByPage(Integer page, Integer limit, ClaimDateNo claimDateNo) {
    Map<String, Object> paramMap = new HashMap<>();
    page = page == null ? 1 : page;
    limit = limit == null ? 20 : limit;

    paramMap.put("page", (page - 1) * limit);
    paramMap.put("limit", limit);
    paramMap.put("claimDateNo", claimDateNo);
    List<ClaimDateNo> list = baseMapper.selectMyPage(paramMap);
    Integer count = baseMapper.countMyPage(paramMap);
    ResultPage<ClaimDateNo> resultPage = new ResultPage<>();
    resultPage.setCode(200);
    resultPage.setCount(count);
    resultPage.setMsg("成功");
    resultPage.setData(list);
    return resultPage;
  }

  @Transactional(isolation = Isolation.REPEATABLE_READ)
  @Override
  public ApiResultModel approvalApproved(Integer claimDateNoId, String userId) {

    // 当前订单的ID
    ClaimDateNo claimDateNo = this.getById(claimDateNoId);
    // 获取要申领的航材和耗材
    List<ClaimGoods> claimGoodsList =
        claimGoodsService.list(
            new LambdaQueryWrapper<ClaimGoods>().eq(ClaimGoods::getClaimId, claimDateNoId));

    for (ClaimGoods claimGoods : claimGoodsList) {
      // 查询物品是航材还是耗材
      Goods goods = goodsService.getById(claimGoods.getGoodsId());

      if (goods.getGoodsType().equals("1")) {
        // 航材更改
        boolean update =
            goodsService.update(
                new LambdaUpdateWrapper<Goods>()
                    .set(Goods::getUserId, claimDateNo.getUserId())
                    .eq(Goods::getUserId, "0")
                    .eq(Goods::getId, claimGoods.getGoodsId()));
        if (!update) {
          throw new RuntimeException("物品" + claimGoods.getGoodsId() + "已归还！");
        }
      } else {
        // 耗材更改 1.查询 仓库的耗材数量

        if (Double.valueOf(goods.getNumber()) < claimGoods.getGoodsCount()) {
          throw new RuntimeException("耗材数量不足请重新申领 该耗材还有：" + goods.getNumber() + goods.getModel());
        }
        // 库里的数量
        BigDecimal number = new BigDecimal(goods.getNumber());
        // 申领的数量
        BigDecimal goodsCount = new BigDecimal(claimGoods.getGoodsCount());

        // 库里剩余数量
        double newNumber = number.subtract(goodsCount).doubleValue();
        boolean updateGoods =
            goodsService.update(
                new LambdaUpdateWrapper<Goods>()
                    .set(Goods::getNumber, newNumber)
                    .eq(Goods::getId, goods.getId()));

        if (!updateGoods) {
          throw new RuntimeException("拿去 库中的物品失败");
        }

        ClaimConsumables claimConsumables = new ClaimConsumables();
        claimConsumables.setGoodsId(claimGoods.getGoodsId());
        claimConsumables.setClaimUserId(userId);
        claimConsumables.setClaimCount(claimGoods.getGoodsCount());

        boolean save = claimConsumablesService.save(claimConsumables);
        if (!save) {
          throw new RuntimeException("耗材" + goods.getGoodsName() + "申领失败");
        }
      }
    }

    boolean UpdateClaimDateNo =
        this.update(
            new LambdaUpdateWrapper<ClaimDateNo>()
                .set(ClaimDateNo::getClaimDateNoState, "2")
                .set(ClaimDateNo::getClaimApprovalUserId, userId)
                .eq(ClaimDateNo::getId, claimDateNoId));

    if (!UpdateClaimDateNo) {
      throw new RuntimeException("申领通过失败");
    }

    return $.success("申领 审批通过！");
  }

  @Override
  public ApiResultModel showApplicationAndReturnDetails(Integer claimDateNoIde) {

    ClaimDateNo claimDateNo = baseMapper.showApplicationAndReturnDetails(claimDateNoIde);

    return $.success(claimDateNo);
  }

  @Override
  public Map downDocClaimDateNo(Integer claimDateNoId) {

    List<ClaimDateNoDocx> data=new ArrayList<>();

    /** 申领单号信息 */
    ClaimDateNo claimDateNo = baseMapper.showApplicationAndReturnDetails(claimDateNoId);
    // 获取所有的物品
    List<ClaimGoods> claimGoodsList = claimDateNo.getClaimGoodsList();

    // 遍历物品
    for (int i = 0; i < claimGoodsList.size(); i++) {
      ClaimDateNoDocx claimDateNoDocx = new ClaimDateNoDocx();
      claimDateNoDocx.setSerialNumber(i + 1);
      claimDateNoDocx.setGoodsName(claimGoodsList.get(i).getGoods().getGoodsName());
      claimDateNoDocx.setModel(claimGoodsList.get(i).getGoods().getGoodsName());
      claimDateNoDocx.setCompany(claimGoodsList.get(i).getGoods().getCompany());

      // 备注 增加原因
      claimDateNoDocx.setRemark(claimGoodsList.get(i).getGoods().getReason());

      double count;

      if(claimGoodsList.get(i).getGoods().getGoodsType().equals("1")){
        // 查询库中 当前物品共计多少件  航材数量
        count = goodsService.count(
                        new LambdaQueryWrapper<Goods>()
                                .eq(Goods::getGoodsName, claimGoodsList.get(i).getGoods().getGoodsName())
                                .eq(Goods::getModel, claimGoodsList.get(i).getGoods().getModel())
                                .eq(Goods::getDateNoId, claimGoodsList.get(i).getGoods().getDateNoId())
                                .eq(Goods::getUserId, "0")
        );
      }else {
        //耗材数量
        count= Double.parseDouble(claimGoodsList.get(i).getGoods().getNumber());

      }


      // 库存数量判定航材耗材
      claimDateNoDocx.setStockNumber(count);

      // 申领数量 判断航材 耗材
      claimDateNoDocx.setClaimNumber(claimGoodsList.get(i).getGoodsCount() == null? 1: claimGoodsList.get(i).getGoodsCount());

      data.add(claimDateNoDocx);
    }

    HashMap<Object, Object> map = new HashMap<>();

    map.put("data",data);


    map.put("date", new Date());

      Unit unit = unitService.getById(claimDateNo.getUnitId());
    String  affiliatedUnits=unit.getUnitName();

    map.put("affiliatedUnits", affiliatedUnits);


    return map;
  }
}
